/**
 * IDE: PhpStorm
 * 组件创建时间: 2022/6/23 10:28
 * 创建作者: Yuxin.Ying
 * 文件路径:
 */

/**
 * 可视区动画功能
 */
class VisibleAnimate {
    /**
     * 实例化参数
     * @param props
     */
    constructor(props) {
        this._props = {
            ...props,
        };
    }

    /**
     * 延迟加载
     * @param fn
     * @param wait
     * @param immediate
     * @returns {(function(): void)|*}
     */
    static debounce(fn, wait, immediate) {
        let timer;
        return function () {
            if (timer) clearTimeout(timer);
            if (immediate) {
                // 如果已经执行过，不再执行
                const callNow = !timer;
                timer = setTimeout(() => {
                    timer = null;
                }, wait);
                if (callNow) {
                    fn.apply(this, arguments);
                }
            } else {
                timer = setTimeout(() => {
                    fn.apply(this, arguments);
                }, wait);
            }
        };
    }

    /**
     * 获取需要控制的DOM
     * @param dom
     * @returns {NodeListOf<Element>}
     */
    static getElement(dom) {
        return document.querySelectorAll(`${dom}`);
    }

    /**
     * @desc 操作
     * @returns {boolean}
     */
    handler() {
        const {
            animateClass,
            boxClass,
            mobile,
            offset,
        } = this._props;

        if (VisibleAnimate.isMobile(navigator.userAgent) && !mobile) {
            return false;
        }

        const box = VisibleAnimate.getElement(boxClass);
        const clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
        const animateClassLen = animateClass.length;
        let animateIndex = -1;
        Array.prototype.forEach.call(box, (boxItem) => {
            if (boxItem.getBoundingClientRect().top + offset < clientHeight) {
                if (animateClass instanceof Array) {
                    if (animateIndex >= animateClassLen - 1) {
                        animateIndex = -1;
                    }
                    ++animateIndex;
                    if (!boxItem.classList.contains('animated')) {
                        boxItem.classList.add('animated');
                        boxItem.classList.add(animateClass[animateIndex]);
                    }
                } else if (typeof animateClass === 'string') {
                    boxItem.classList.add('animated');
                    boxItem.classList.add(animateClass);
                } else {
                    throw new Error(`期待值是字符串或数组, 您传入的是${typeof animateClass}`);
                }
            }
        });
    }

    /**
     * @desc 判断是否处于移动端
     * @param userAgent
     * @returns {boolean}
     */
    static isMobile(userAgent) {
        return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent));
    }

    /**
     * 初始化
     */
    init() {
        this.handler();
        const {
            delay,
        } = this._props;
        window.addEventListener('scroll', VisibleAnimate.debounce(this.handler, delay || 200).bind(this));
    }
}

// export default VisibleAnimate;
